home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 October: Windmill on DISC / ADC Developer CD (1993-10) (''Windmill On DISC'')_iso / Dev.CD Oct 93.iso / System Software / U.S. System Software / System 7 Pro™ Beta 11 / Development Tools / Sample Code / Interprogram Messaging Manager / IPM MessageBoard / MyIPM.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-28  |  18.5 KB  |  799 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * IPM MessageBoard AOCE Sample
  4.  *
  5.  * ©1992-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * commands.c -- called in response to menu commands or appleevents
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        2/12/93        1.0b1        udpate to AOCE beta seed
  14.  * SJF        11/6/91        1.0d1        initial coding
  15.  *
  16.  */
  17.  
  18. #ifndef __TOOLUTILS__
  19. #include <ToolUtils.h>
  20. #endif
  21.  
  22. #ifndef __RESOURCES__
  23. #include <Resources.h>
  24. #endif
  25.  
  26. #include <string.h>
  27.  
  28. #ifndef    __OCE__
  29. #include <OCE.h>
  30. #endif
  31.  
  32. #ifndef __OCEMESSAGING__
  33. #include <OCEMessaging.h>
  34. #endif
  35.  
  36. #ifndef __OCEERRORS__
  37. #include <OCEErrors.h>
  38. #endif
  39.  
  40. #ifndef __OCESTANDARDMAIL__
  41. #include <OCEStandardMail.h>
  42. #endif
  43.  
  44. #ifndef __OCESTANDARDDIRECTORY__
  45. #include <OCEStandardDirectory.h>
  46. #endif
  47.  
  48. #ifndef __OCETEMPLATES__
  49. #include <OCETemplates.h>
  50. #endif
  51.  
  52. #ifdef applec
  53. #include <strings.h>    // for c2pstr
  54. #endif
  55.  
  56. #include "const.h"
  57. #include "globals.h"
  58. #include "utils.h"
  59. #include "queues.h"
  60. #include "statusdialog.h"
  61. #include "AddressOMini.h"
  62.  
  63. #include "myipm.h"
  64. #include "GetAttribute.h"
  65.  
  66.  
  67. /*---------- init/cleanup stuff ---------------------------------------------------------*/
  68.  
  69. OSErr InitIPM(void)
  70. {
  71.     OSErr err;
  72.     
  73.     gNumMessages = 0;
  74.     gNumDestinations = 0;
  75.     err = GetIdentity();
  76.     if (err!=noErr)
  77.         return err;
  78.     return MakeLocalQueue(&gIPMContext,&gIPMQueueRef);
  79. }
  80.  
  81.  
  82. void CloseIPM(void)
  83. {
  84.     OSErr err;
  85.     
  86.     err = RemoveLocalQueue(gIPMContext,&gLocalQueue);
  87.     if (err!=noErr)
  88.         DoError(err);
  89. }
  90.  
  91.  
  92. /*---------- queue management stuff ------------------------------------------------------*/
  93.  
  94.  
  95. OSErr MakeLocalQueue(IPMContextRef *context,IPMQueueRef *queueRef)
  96. {
  97.     IPMParamBlock pmBlock;
  98.     OSErr err;
  99.     
  100.     *context = 0;
  101.     *queueRef = 0;
  102.     
  103.     err = GetLocalQueueLocation(&gLocalQueue,kQueueName,gLocalQXtn);
  104.     if (err!=noErr)
  105.         return err;
  106.     
  107.     // create queue
  108.     
  109.     pmBlock.createQueuePB.queue = &gLocalQueue;
  110.     pmBlock.createQueuePB.identity = gIdentity;
  111.     pmBlock.createQueuePB.owner = nil;
  112.     pmBlock.createQueuePB.ioCompletion = nil;
  113.     IPMCreateQueue(&pmBlock,true);
  114.     err = WaitPBDone(&pmBlock);
  115.     if (err!=noErr && err!=kOCEAlreadyExists)
  116.         return err;
  117.     
  118.     // open context
  119.     
  120.     IPMOpenContext(&pmBlock,true);
  121.     err = WaitPBDone(&pmBlock);
  122.     if (err!=noErr)
  123.         return err;
  124.     *context = pmBlock.openContextPB.contextRef;
  125.     
  126.     // open queue
  127.     
  128.     pmBlock.openQueuePB.filter = nil;
  129.     pmBlock.openQueuePB.noteType = kIPMNewMsgMask;
  130.  
  131.     pmBlock.openQueuePB.notificationProc = OurIPMNotificationProc;
  132.     pmBlock.openQueuePB.userData = SetCurrentA5();
  133.     IPMOpenQueue(&pmBlock,true);
  134.     err = WaitPBDone(&pmBlock);
  135.     if (err!=noErr)
  136.         return err;
  137.     
  138.     gIPMQueueRef = pmBlock.openQueuePB.newQueueRef;
  139.     return noErr;
  140. }
  141.  
  142.  
  143. OSErr RemoveLocalQueue(IPMContextRef context,OCERecipient *localQueue)
  144. {
  145.     IPMParamBlock pmBlock;
  146.     OSErr err;
  147.     
  148.     if (context) {
  149.         pmBlock.closeContextPB.contextRef = context;
  150.         pmBlock.closeContextPB.ioCompletion = nil;
  151.         err = IPMCloseContext(&pmBlock,true);
  152.         err = WaitPBDone(&pmBlock);
  153.         if (err!=noErr)
  154.             return err;
  155.     }
  156.     
  157.     pmBlock.deleteQueuePB.queue = localQueue;
  158.     pmBlock.deleteQueuePB.identity = gIdentity;
  159.     pmBlock.deleteQueuePB.ioCompletion = nil;
  160.     IPMDeleteQueue(&pmBlock,true);
  161.     err = WaitPBDone(&pmBlock);
  162.     
  163.     return err;
  164. }
  165.  
  166.  
  167. OSErr GetLocalQueueLocation(OCERecipient *queue,StringPtr queueName,char *xtnValue)
  168. {
  169.     XPPParamBlock xppPB;
  170.     Str32 zoneName;
  171.     StringHandle machineName;
  172.     char *offset;
  173.     OSErr err;
  174.     short i;
  175.     
  176.     for (i=0; i<256; i++)
  177.         xtnValue[i] = '\0';
  178.         
  179.     xppPB.XCALL.xppTimeout = 3;
  180.     xppPB.XCALL.xppRetry = 4;
  181.     xppPB.XCALL.zipBuffPtr = (Ptr)&zoneName;
  182.     xppPB.XCALL.zipInfoField[0] = 0;
  183.     xppPB.XCALL.zipInfoField[1] = 0;
  184.     err = GetMyZone(&xppPB,false);
  185.     if (err!=noErr)
  186.         return err;
  187.     
  188.     machineName = GetString(kMachineNameResource);
  189.     if (ResError()!=noErr)
  190.         return ResError();
  191.     
  192.     offset = xtnValue;
  193.     BlockMove(*machineName,offset,(*machineName)[0]+1);
  194.     offset = offset+(*machineName)[0]+1;
  195.     
  196.     ReleaseResource((Handle)machineName);
  197.     
  198.     BlockMove(kIPMWSReceiverNBPType,offset,kIPMWSReceiverNBPType[0]+1);
  199.     offset = (offset+kIPMWSReceiverNBPType[0]+1);
  200.     
  201.     BlockMove(zoneName,offset,zoneName[0]+1);
  202.     offset = (offset+zoneName[0]+1);
  203.     
  204.     BlockMove(queueName,offset,queueName[0]+1);
  205.     offset = (offset+queueName[0]+1);
  206.     
  207.     queue->entitySpecifier = nil;    // we don't need one for direct specification
  208.     queue->extensionType = kOCEalanXtn;
  209.     queue->extensionValue = xtnValue;
  210.     queue->extensionSize = StripAddress(offset)-StripAddress(xtnValue);
  211.     
  212.     return noErr;
  213. }
  214.  
  215.  
  216. /*---------- message sending stuff ------------------------------------------------------*/
  217.  
  218.  
  219. OSErr SendIPMMessage(StringPtr message,OCEPackedRecipient *packedQueue)
  220. {
  221.     OSErr err,err2;
  222.     IPMParamBlock pmBlock;
  223.     OCERecipient queue;
  224.     RecordID entitySpecifier;
  225.     IPMProcHint procHint;
  226.     short i;
  227.     IPMMsgType msgType;
  228.     IPMSender sender;
  229.     RString messageTitle;
  230.     
  231.     // zero out proc hint
  232.     
  233.     for (i=0; i<sizeof(IPMProcHint); i++)
  234.         procHint[i] = 0;
  235.     
  236.     // unpack destination recipient
  237.     
  238.     OCEUnpackDSSpec((PackedDSSpec*)packedQueue,&queue,&entitySpecifier);
  239.  
  240.     // get message type and sender
  241.     
  242.     GetOurMessageType(&msgType);
  243.     GetOurSender(&sender);
  244.     
  245.     // make a new message
  246.     
  247.     pmBlock.newMsgPB.ioCompletion = nil;
  248.     pmBlock.newMsgPB.recipient = &queue;
  249.     
  250.     pmBlock.newMsgPB.replyQueue = &gLocalQueue;        
  251.     pmBlock.newMsgPB.procHint = procHint;
  252.     
  253.     pmBlock.newMsgPB.msgType = &msgType;
  254.     pmBlock.newMsgPB.identity = gIdentity;
  255.     pmBlock.newMsgPB.sender = &sender;
  256.     IPMNewMsg(&pmBlock,true);
  257.     err = WaitPBDone(&pmBlock);
  258.     if (err!=noErr)
  259.         return err;
  260.     
  261.     // make a block within that message
  262.     
  263.     pmBlock.newBlockPB.msgRef = pmBlock.newMsgPB.newMsgRef;
  264.     pmBlock.newBlockPB.blockType.msgType = kAppBlockType;
  265.     pmBlock.newBlockPB.blockType.msgCreator = kAppCreator;
  266.     pmBlock.newBlockPB.refCon = 0;
  267.     IPMNewBlock(&pmBlock,true);
  268.     err = WaitPBDone(&pmBlock);
  269.     if (err==noErr) {
  270.     
  271.         // write block data
  272.         
  273.         pmBlock.writeMsgPB.offset = pmBlock.newBlockPB.startingOffset;
  274.         pmBlock.writeMsgPB.mode = kIPMFromStart;
  275.         pmBlock.writeMsgPB.count = message[0]+1;
  276.         pmBlock.writeMsgPB.buffer = (Ptr)message;
  277.         pmBlock.writeMsgPB.currentBlock = true;
  278.         IPMWriteMsg(&pmBlock,true);
  279.         err = WaitPBDone(&pmBlock);
  280.     
  281.     }
  282.     
  283.     // end the message
  284.     
  285.     OCECToRString((char *)"message\n",smRoman,&messageTitle,kRStringMaxBytes);
  286.  
  287.     pmBlock.endMsgPB.deliveryNotification = 0;
  288.     pmBlock.endMsgPB.priority = kIPMNormalPriority;
  289.     pmBlock.endMsgPB.cancel = (err!=noErr);
  290.     pmBlock.endMsgPB.signature = nil;
  291.     pmBlock.endMsgPB.signatureSize = 0;
  292.     pmBlock.endMsgPB.signatureContext = nil;
  293.     pmBlock.endMsgPB.msgTitle = &messageTitle;
  294.     IPMEndMsg(&pmBlock,true);
  295.     err2 = WaitPBDone(&pmBlock);
  296.     
  297.     if (err!=noErr)
  298.         return err;
  299.     else
  300.         return err2;
  301. }
  302.  
  303.  
  304.  
  305. OSErr GetIdentityAndSaveIt (void)
  306. {
  307.     OSErr            err;
  308.     SDPIdentityKind     selectedKind;
  309.  
  310.     if ((err = SDPPromptForID (&gIdentity, "\pPlease Validate Your Identity:",
  311.                                 "\pPlease Validate Your Identity:",
  312.                                 "\pPlease Validate Your Identity:", 
  313.                                 OCEGetIndRecordType (kUserRecTypeNum),
  314.                                 kSDPSpecificIdentityMask, &selectedKind, NULL, NULL)) != noErr)
  315.         gIdentity = 0L;
  316.  
  317.     return (err);
  318. }
  319.  
  320.  
  321. OSErr GetNewIdentityAndSaveIt (AuthIdentity *theIdentity)
  322. {
  323.     OSErr            err;
  324.     SDPIdentityKind     selectedKind;
  325.  
  326.     if ((err = SDPPromptForID (theIdentity, "\pEnter Authentication Identity Of The Queue Creator:",
  327.                                 "\pEnter Authentication Identity Of The Queue Creator:",
  328.                                 "\pEnter Authentication Identity Of The Queue Creator:", 
  329.                                 OCEGetIndRecordType (kUserRecTypeNum),
  330.                                 kSDPSpecificIdentityMask, &selectedKind, NULL, NULL)) != noErr)
  331.         *theIdentity = 0L;
  332.  
  333.     return (err);
  334. }
  335.  
  336.  
  337. OSErr MyCreateQueue(StringPtr TheQName,OCEPackedRecipient **pmPackedRecipient)
  338. {
  339. OSErr err;
  340. IPMParamBlock IPMpb;
  341. OCERecipient theRecp,OwnerRecp;
  342. RecordID QLocRid,OwnerRid,testRecID;
  343. Boolean gotAddress;
  344. PackedDSSpecPtr packedReply,packedReply2;
  345. PackedRecordIDPtr testPckRecID;
  346. unsigned short ridSize;
  347. //AuthIdentity theIdentity;
  348. IPMEntityNameExtension TheExtn;
  349. unsigned long recipLength;
  350.  
  351.  
  352.     gotAddress = AddressOMini(&packedReply,gTypesList,0,gIdentity,
  353.             kEnumAllMask,"\pSelect The Server Record:",kMatchAll);
  354.  
  355.     if (gotAddress==false)
  356.         return kUserCancelled;
  357.  
  358.     if (packedReply) 
  359.     {
  360.         OCEUnpackDSSpec(packedReply,&theRecp,&QLocRid);
  361.  
  362.         TheExtn.subExtensionType = kOCEQnamXtn;    //    'qnam'
  363.         pstrcpy((Ptr)&TheExtn.u.queue.queueName,TheQName);
  364.  
  365.         theRecp.extensionType = kOCEentnXtn;    // 'entn'
  366.         theRecp.extensionValue = (Ptr)&TheExtn;
  367.         theRecp.extensionSize = (TheExtn.u.queue.queueName[0] + 1) + sizeof(OSType);        
  368.         
  369.         IPMpb.createQueuePB.queue = &theRecp;
  370.  
  371. #if 0        
  372.             // let user identify the creator of the queue
  373.         GetNewIdentityAndSaveIt (&theIdentity);
  374.         IPMpb.createQueuePB.identity = theIdentity;
  375. #endif
  376. IPMpb.createQueuePB.identity = gIdentity;
  377.  
  378.         gotAddress = AddressOMini(&packedReply2,gTypesList,0,gIdentity,
  379.                 kEnumAllMask,"\pSelect The User Record Of The Queue Owner:",kMatchAll);
  380.     
  381.         if (gotAddress==false)
  382.             return kUserCancelled;
  383.     
  384.         if (packedReply2) 
  385.         {
  386.             OCEUnpackDSSpec(packedReply2,&OwnerRecp,&OwnerRid);
  387.  
  388.             OCENewRecordID(OwnerRid.rli,&OwnerRid.local,&testRecID);
  389.             ridSize = OCEPackedRecordIDSize(&OwnerRid);
  390.             testPckRecID = (PackedRecordIDPtr)NewPtr(ridSize);
  391.             if ((err = MemError()) != noErr)
  392.                 return err;
  393.             if ((err = OCEPackRecordID(&testRecID,testPckRecID,ridSize)) != noErr)
  394.                 return err;
  395.             
  396.             IPMpb.createQueuePB.owner = testPckRecID;
  397.             if ((err = IPMCreateQueue(&IPMpb,false)) != noErr)
  398.                 return err;
  399.         }
  400.         if (testPckRecID != nil)
  401.             DisposePtr((Ptr)testPckRecID);
  402.             
  403.         recipLength = OCEPackedDSSpecSize(&theRecp);
  404.         *pmPackedRecipient = NewPtrChk(recipLength);
  405.         if ((err=MemError())==noErr) 
  406.             OCEPackDSSpec(&theRecp,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  407.         else
  408.             return err;
  409.     }
  410.     
  411.     return err;
  412. }
  413.  
  414. OSErr MyOpenQueue(OCERecipient *RecP)
  415. {
  416. OSErr err;
  417. IPMParamBlock IPMpb;
  418. IPMContextRef cRef;
  419.  
  420.  
  421.     IPMpb.openContextPB.ioCompletion = nil;
  422.     if ((err = IPMOpenContext(&IPMpb,false)) != noErr)
  423.         return err;
  424.     else
  425.         cRef = IPMpb.openContextPB.contextRef;
  426.     
  427.     IPMpb.openQueuePB.ioCompletion = nil;
  428.     IPMpb.openQueuePB.contextRef = cRef;
  429.     
  430.     IPMpb.openQueuePB.queue = RecP;
  431.     IPMpb.openQueuePB.identity = gIdentity;
  432.     IPMpb.openQueuePB.filter = nil;
  433.     
  434.     if ((err = IPMOpenQueue(&IPMpb,false)) != noErr)
  435.         return err;
  436.  
  437.     return err;
  438. }
  439.  
  440. OSErr OpenQueueOnRemoteMachine(StringPtr Qname,OCEPackedRecipient **pmPackedRecipient)
  441. {
  442. OSErr err;
  443. PackedDSSpecPtr packedReply;
  444. PackedRStringListHandle catTypes = nil;
  445. OCERecipient ipmRecipient;
  446. unsigned long recipLength;
  447. Boolean gotAddress;
  448. RecordID rid;
  449. IPMEntityNameExtension myExtn;
  450.  
  451.  
  452.  
  453. //    if ((err = GetIdentityAndSaveIt()) == noErr)
  454. //    {
  455.         gotAddress = AddressOMini(&packedReply,gTypesList,0,gIdentity,
  456.                 kEnumAllMask,"\pSelect The Server Record:",kMatchAll);
  457.     
  458.         if (gotAddress==false)
  459.             return kUserCancelled;
  460.     
  461.         if (packedReply) 
  462.         {
  463.             OCEUnpackDSSpec(packedReply,&ipmRecipient,&rid);
  464.             ipmRecipient.extensionType = kOCEentnXtn;    // 'entn'
  465.             
  466.             myExtn.subExtensionType = kOCEQnamXtn;    //    'qnam'
  467.             pstrcpy((Ptr)&myExtn.u.queue.queueName,Qname);
  468.             
  469.             ipmRecipient.extensionSize = (myExtn.u.queue.queueName[0] + 1) + sizeof(OSType);
  470.             ipmRecipient.extensionValue = (Ptr)&myExtn;
  471.     
  472.             if ((err = MyOpenQueue(&ipmRecipient)) == noErr)
  473.             {
  474.         
  475.                 recipLength = OCEPackedDSSpecSize(&ipmRecipient);
  476.                 *pmPackedRecipient = NewPtrChk(recipLength);
  477.                 if ((err=MemError())==noErr) 
  478.                     OCEPackDSSpec(&ipmRecipient,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  479.                 else
  480.                     return err;
  481.             }
  482.     
  483.         }
  484. //    }
  485.     
  486.     return err;
  487. }
  488.  
  489.  
  490.  
  491. OSErr GetSingleAttrForRecipient(OCEPackedRecipient **pmPackedRecipient,
  492.                                 const OCEAttributeTypeIndex stringIndex)
  493. {
  494. OSErr err;
  495. PackedDSSpecPtr packedReply;
  496. unsigned long recipLength;
  497. Boolean gotAddress;
  498. AttributePtr theAttribute;
  499. OCERecipient dss;
  500. RecordID rid;
  501. IPMEntityNameExtension myExtn;
  502.  
  503.  
  504.  
  505.     gotAddress = AddressOMini(&packedReply,&gTypesList,0,gIdentity,
  506.             kEnumAllMask,"\pSelect The User Record:",kMatchAll);
  507.  
  508.     if (gotAddress==false)
  509.         return kUserCancelled;
  510.  
  511.     if (packedReply) 
  512.     {
  513.         OCEUnpackDSSpec(packedReply,&dss,&rid);
  514.  
  515.         if ((err = GetAttributeFromRID (&rid, OCEGetIndAttributeType (stringIndex),
  516.                                     &theAttribute, gIdentity)) != noErr)
  517.             return err;
  518.         dss.extensionType = kOCEentnXtn;    // 'entn'
  519.  
  520.         myExtn.subExtensionType = kOCEAttrXtn;    //    'attr'
  521.         OCECopyRString((RStringPtr)&theAttribute->attributeType,(RStringPtr)OCEGetIndAttributeType(stringIndex),kAttributeTypeMaxBytes);
  522.  
  523. // #################
  524.         dss.extensionSize = sizeof(ProtoRString) + theAttribute->attributeType.dataLength + sizeof(OSType);
  525.         dss.extensionValue = (Ptr)&myExtn;
  526.  
  527.         recipLength = OCEPackedDSSpecSize(&dss);
  528.         *pmPackedRecipient = NewPtrChk(recipLength);
  529.         if ((err=MemError())==noErr)
  530.         OCEPackDSSpec(&dss,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  531.  
  532.         DisposPtr((Ptr)packedReply);
  533.  
  534.     }
  535.     
  536.     return err;
  537. }
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544. OSErr GetIPMDestination(OCEPackedRecipient **pmPackedRecipient)
  545. {
  546.     PackedDSSpecPtr packedReply;
  547.     OSErr err;
  548.     RString addressCategory;
  549.     unsigned short numTypes;
  550.     PackedRStringListHandle catTypes;
  551.     RString *typeList[kMaxPathParts];
  552.     unsigned char hState;
  553.     OCERecipient *ipmRecipient;
  554.     char newXtnValue[256];
  555.     unsigned long newXtnLength,recipLength;
  556.     SMPRecipientDescriptorPtr recipList,freeRecip;
  557.     Boolean gotAddress;
  558.     
  559.     /* display address records */
  560.     
  561.     OCECToRString(kDETCategoryAddressItems,smRoman,&addressCategory,kRStringMaxBytes);
  562.     err = SDPGetCategoryTypes(&addressCategory,&catTypes);
  563.     if (err!=noErr)
  564.         return err;
  565.     hState = HGetState((Handle)catTypes);
  566.     HLock((Handle)catTypes);
  567.     numTypes = OCEUnpackPathName(*catTypes,typeList,kMaxPathParts);    
  568.  
  569.     gotAddress = AddressOMini(&packedReply,typeList,numTypes,gIdentity,
  570.             kEnumDistinguishedNameMask|kEnumAliasMask|kEnumDNodeMask,"\pSelect Atalk Address:",kExactMatch);
  571.  
  572.     HSetState((Handle)catTypes,hState);
  573.     if (gotAddress==false)
  574.         return kUserCancelled;
  575.     
  576.     if (packedReply) {
  577.         err = SMPResolveToRecipient(packedReply,&recipList,gIdentity);
  578.         ipmRecipient = &recipList->theAddress;
  579.         newXtnLength = ipmRecipient->extensionSize;
  580.         BlockMove(ipmRecipient->extensionValue,newXtnValue,newXtnLength);
  581.         BlockMove(kQueueName,newXtnValue+newXtnLength,kQueueName[0]+1);
  582.         newXtnLength += kQueueName[0]+1;
  583.         ipmRecipient->extensionSize = newXtnLength;
  584.         ipmRecipient->extensionValue = newXtnValue;
  585.     }
  586.  
  587.     // pack the recipient
  588.     
  589.     recipLength = OCEPackedDSSpecSize(ipmRecipient);
  590.     *pmPackedRecipient = NewPtrChk(recipLength);
  591.     if ((err=MemError())==noErr) {
  592.         OCEPackDSSpec(ipmRecipient,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  593.     }
  594.     DisposPtr((Ptr)packedReply);
  595.  
  596.     // free the resolvetorecipients result
  597.     
  598.     while (recipList!=nil) {
  599.         freeRecip = recipList;
  600.         recipList = recipList->next;
  601.         DisposPtrChk(freeRecip->recipient);
  602.         DisposPtrChk(freeRecip);
  603.     }
  604.     
  605.     return err;
  606. }
  607.  
  608.  
  609. void GetDestAsString(short destNum,StringPtr destStr)
  610. {
  611.     OCERecipient recipient;
  612.     RecordID entitySpecifier;
  613.     StringPtr displayName;
  614.     
  615.     OCEUnpackDSSpec((PackedDSSpec *)gDestList[destNum],&recipient,&entitySpecifier);
  616.     displayName = OCERToPString(entitySpecifier.local.recordName);
  617.     pstrcpy(destStr,displayName);
  618. }
  619.  
  620.  
  621. void r2cString(RString *rStr,char *cStr)
  622. {
  623.     StringPtr pStr;
  624.     
  625.     pStr = OCERToPString(rStr);
  626.     pstrcpy((StringPtr)cStr,pStr);
  627.     p2cstr((StringPtr)cStr);
  628. }
  629.  
  630.  
  631. void GetOurMessageType(IPMMsgType *msgType)
  632. {
  633.     msgType->format = kIPMOSFormatType;
  634.     msgType->theType.msgOSType.msgCreator = kAppCreator;
  635.     msgType->theType.msgOSType.msgType = kAppMessageType;
  636. }
  637.  
  638.  
  639. void GetOurSender(IPMSender *sender)
  640. {
  641.     Str255 appName;
  642.     Handle appParms;
  643.     short refNum;
  644.     
  645.     GetAppParms(appName,&refNum,&appParms);
  646.     OCEPToRString(appName,smSystemScript,&sender->theSender.rString,kRStringMaxBytes);
  647.     sender->sendTag = kIPMSenderRStringTag;
  648. }
  649.  
  650.  
  651. OSErr GetIdentity(void)
  652. {
  653.     OSErr err;
  654.     SDPIdentityKind idKind;
  655.     AuthGetLocalIdentityPB pBlock;
  656.     
  657.     err = AuthGetLocalIdentity((AuthParamBlockPtr)&pBlock,false);
  658.  
  659.     if (err!=noErr)
  660.         err = SDPPromptForID(&gIdentity,nil,nil,kLocalIDPrompt,nil,kSDPLocalIdentityMask,&idKind,nil,0);
  661.     else
  662.         gIdentity = pBlock.theLocalIdentity;
  663.         
  664.     return err;
  665. }
  666.  
  667.  
  668.  
  669. /*---------- message receiving stuff ------------------------------------------------------*/
  670.  
  671.  
  672. pascal void OurIPMNotificationProc(IPMQueueRef pmQ, IPMSeqNum pmSeq, IPMNotificationType noteType, unsigned long userData)
  673. {
  674.     long savedA5;
  675.     unsigned char noteTypeChar;
  676.  
  677.     noteTypeChar = (unsigned char) (noteType &= 0x000000ff);
  678.     savedA5 = SetA5(userData);
  679.     EnqueueNotification(pmQ,pmSeq,noteType);
  680.     SetA5(savedA5);
  681. }
  682.  
  683.  
  684. void EnqueueNotification(IPMQueueRef pmQ, IPMSeqNum pmSeq, IPMNotificationType noteType)
  685. {
  686.     MyQElemPtr qBlock;
  687.     
  688.     qBlock = GetUnusedQBlock();
  689.     if (!qBlock) {
  690.         DoError(kNoMemory);
  691.         return;
  692.     }
  693.     
  694.     qBlock->pmQ = pmQ;
  695.     qBlock->pmSeq = pmSeq;
  696.     qBlock->noteType = noteType;
  697.     
  698.     StoreCompletedQBlock(qBlock);
  699. }
  700.  
  701.  
  702. void ProcessNotification(MyQElemPtr qBlock)
  703. {
  704.     OSErr err;
  705.     
  706.     err = noErr;
  707.     
  708.     if (qBlock->noteType==kIPMNewMsgMask)
  709.         err = ProcessNewMessage(qBlock->pmQ,qBlock->pmSeq);
  710.     
  711.     if (err!=noErr)
  712.         DoError(err);
  713.         
  714.     RecycleFreeQBlock(qBlock);
  715. }
  716.  
  717.  
  718. OSErr ProcessNewMessage(IPMQueueRef pmQ, IPMSeqNum pmSeq)
  719. {
  720.     OSErr err;
  721.     IPMParamBlock pmBlock;
  722.     IPMMsgInfo msgInfo;
  723.     Str255 msgBuffer;
  724.     
  725.     // open the message
  726.     
  727.     pmBlock.openMsgPB.ioCompletion = nil;
  728.     pmBlock.openMsgPB.queueRef = pmQ;
  729.     pmBlock.openMsgPB.sequenceNum = pmSeq;
  730.     pmBlock.openMsgPB.exactMatch = true;
  731.     IPMOpenMsg(&pmBlock,true);
  732.     err = WaitPBDone(&pmBlock);
  733.     if (err!=noErr)
  734.         return err;
  735.     
  736.     // get message header
  737.     
  738.     pmBlock.getMsgInfoPB.msgRef = pmBlock.openMsgPB.newMsgRef;
  739.     pmBlock.getMsgInfoPB.info = &msgInfo;
  740.     IPMGetMsgInfo(&pmBlock,true);
  741.     err = WaitPBDone(&pmBlock);
  742.     if (err!=noErr)
  743.         return BailMessageProcessing(&pmBlock,err);
  744.     
  745.     // get message block index
  746.     
  747.     pmBlock.getBlkIndexPB.blockType.msgType = kAppBlockType;
  748.     pmBlock.getBlkIndexPB.blockType.msgCreator = kAppCreator;
  749.     pmBlock.getBlkIndexPB.index = 1;
  750.     pmBlock.getBlkIndexPB.startingFrom = 1;
  751.     IPMGetBlkIndex(&pmBlock,true);
  752.     err = WaitPBDone(&pmBlock);
  753.     if (err!=noErr)
  754.         return BailMessageProcessing(&pmBlock,err);
  755.     
  756.     // get the message block
  757.     
  758.     pmBlock.readMsgPB.blockIndex = pmBlock.getBlkIndexPB.actualBlockIndex;
  759.     pmBlock.readMsgPB.mode = kIPMFromStart;
  760.     pmBlock.readMsgPB.offset = 0;
  761.     pmBlock.readMsgPB.count = sizeof(Str255);
  762.     pmBlock.readMsgPB.buffer = (Ptr)msgBuffer;
  763.     IPMReadMsg(&pmBlock,true);
  764.     err = WaitPBDone(&pmBlock);
  765.     if (err!=noErr)
  766.         return BailMessageProcessing(&pmBlock,err);
  767.     
  768.     // add message to list
  769.     
  770.     if (gNumMessages!=kMaxMessages) {
  771.         pstrcpy(gMessageList[gNumMessages],msgBuffer);
  772.         AddItemToList(gNumMessages,kMsgListDItem);
  773.         gNumMessages++;
  774.     }
  775.     else SysBeep(1);    // no room in list
  776.  
  777.     return BailMessageProcessing(&pmBlock,err);
  778. }
  779.  
  780.  
  781. /* delete the message and exit with the passed in error code */
  782.  
  783. OSErr BailMessageProcessing(IPMParamBlock *pmBlock,OSErr err)
  784. {
  785.     OSErr err2;
  786.     
  787.     // delete the message
  788.  
  789.     pmBlock->closeMsgPB.deleteMsg = true;
  790.     IPMCloseMsg(pmBlock,true);
  791.     err2 = WaitPBDone(pmBlock);
  792.     
  793.     if (err==noErr)
  794.         return err2;
  795.     else
  796.         return err;
  797. }
  798.  
  799.